//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2003 Intrinsyc Europe Ltd.
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004 Siemens AG
//
// Version: 1.1.2.5
// Date:    11. Jan. 2006
//////////////////////////////////////////////////////////////////////////////
//
//
// (C) Copyright 2007 Marvell International Ltd.
//  All Rights Reserved
//


#include "precomp.h"

extern RHA_FUNCTION_LIST RHAFunctionList;

//
//
//
BOOL CRilHandle::ExSendATCommand(COM_PORT_TYPE PortType, char *pszATCommand) 
{
DWORD dwWritten;

  if (!RHAFunctionList.pfnRHA_IsRadioPwrOn()) 
  {
    RILRetailTrace((TEXT("RilDrv: ExSendATCommand (PortType = %d) - Module powered off externally\r\n"), PortType));
    g_PowerManager.ForcePowerOff();
    return FALSE;
  }

	if (PortType != RIL_BASE_PORT_TYPE)
	{
		ExtRILRetailTrace(TEXT("RilDrv: ExSendATCommand(%s): "), g_ComManager.GetDebugName(PortType), pszATCommand);
	}
	else
	{
		RILRetailTrace((TEXT("RilDrv: ExSendATCommand(Base Port)\r\n")));   			 
	}

    return DOWNST_WRITEFILE(g_ComManager.GetPortHandle(PortType), pszATCommand, strlen(pszATCommand), &dwWritten);
}

//
//
//
BOOL CRilHandle::ExGetATResponse(COM_PORT_TYPE PortType, char *pszATResponse, UINT uiBufLen, DWORD dwTimeout, BOOL fIgnoreTimeout) 
{
const char*  szAcceptedResponses[] = { "OK\r\n", "ERROR\r\n", "0\r", "4\r", "" };
char*        pszResponse;
DWORD        dwBytesRead;
DWORD        dwResponsePos;
DWORD        dwStartTime;
UINT         uiBufferLength;

  // Clear the response buffer
  memset(pszATResponse, 0, uiBufLen);
  uiBufLen--;
  uiBufferLength = uiBufLen;
  pszResponse = pszATResponse;

  dwStartTime = GetTickCount();
  while (TRUE) 
  {
    // Wait for some data
    if (!DOWNST_READFILE(g_ComManager.GetPortHandle(PortType), pszATResponse, uiBufLen, &dwBytesRead)) 
    {
      RILRetailTrace((TEXT("RilDrv: ExGetATResponse(%d) - ReadFile failed\r\n"), PortType));
      return FALSE;
    }

    // Check if we have received some data
    if (dwBytesRead > 0) 
    {
      // Scan for possible responses
      for (dwResponsePos = 0; strlen(szAcceptedResponses[dwResponsePos]); dwResponsePos++) 
      {
        if (FindString(0, pszResponse, (char*)szAcceptedResponses[dwResponsePos], uiBufferLength, 0)) 
        {
		    if (PortType == RIL_BASE_PORT_TYPE)
		  	{
	    	  	ExtRILRetailTrace(TEXT("RilDrv: ExGetATResponse(%s): "), TEXT("Base Port"), pszATResponse);
		  	}
	    	else
    	  	{
	    	  	ExtRILRetailTrace(TEXT("RilDrv: ExGetATResponse(%s): "), g_ComManager.GetDebugName(PortType), pszATResponse);
		  	}

          return TRUE;
        }
      }

      pszATResponse += dwBytesRead;
      uiBufLen -= dwBytesRead;
      if (uiBufLen <= 0) {
        RILRetailTrace((TEXT("RilDrv: ExGetATResponse(%d) - buffer overflow\r\n"), PortType));
        return FALSE;
      }
    }

    if ((GetTickCount() -dwStartTime) >= dwTimeout) 
    {
      RILRetailTrace((TEXT("RilDrv: ExGetATResponse(%d) - timeout\r\n"), PortType));
      if (!fIgnoreTimeout) 
      {
        char szRspAT[32];
        if (!ExSendATCmdGetRsp(PortType, "AT\r", szRspAT, sizeof(szRspAT), 1000, 0, TRUE)) 
        {
          BroadcastDWORDBlobNotification(RIL_NOTIFY_DEVSPECIFIC_EMERG_SHUTDOWN, EMERG_SHUTDOWN_POWERLOSS);
          g_PowerManager.ForcePowerOff();
        }
      }
      return FALSE;
    }

    if (!RHAFunctionList.pfnRHA_IsRadioPwrOn()) 
    {
      RILRetailTrace((TEXT("RilDrv: ExGetATResponse(%s) - Module powered off externally\r\n"), g_ComManager.GetDebugName(PortType)));
      g_PowerManager.ForcePowerOff();
      return FALSE;
    }

    Sleep(125);
  };

  return FALSE;
}

//
//
//
BOOL CRilHandle::ExSendATCmdGetRsp(COM_PORT_TYPE PortType, char *pszATCommand, char *pszATResponse, UINT uiBufLen, DWORD dwTimeout, DWORD dwRetries, BOOL fIgnoreTimeout) 
{
  for (DWORD i = 0; (i <= dwRetries) && RHAFunctionList.pfnRHA_IsRadioPwrOn(); i++) 
  {
    if (i) 
    {
	  if (PortType != RIL_BASE_PORT_TYPE)
    	{
        	RILRetailTrace((TEXT("RilDrv: ExSendATCmdGetRsp(%s): Retrying command\r\n"), g_ComManager.GetDebugName(PortType)));
    	}
    	else
    	{
			RILRetailTrace((TEXT("RilDrv: ExSendATCmdGetRsp(Base Port): Retrying command\r\n")));   			 
        }

        Sleep(100);
    }

    if (!ExSendATCommand(PortType, pszATCommand)) 
    {
      return FALSE;
    }

    if (ExGetATResponse(PortType, pszATResponse, uiBufLen, dwTimeout, fIgnoreTimeout)) 
    {
      return TRUE;
    }
  }

  return FALSE;
}

